use bytes::{Buf, BufMut, Bytes, BytesMut};
use tools::{
	error::Error,
	utils::{get_bits_value, write_to_bits, BitsField},
};

use crate::Codec;

// #[cfg(target_endian = "big")]
// #[cfg(target_endian="little")]

const V: BitsField = BitsField {
	position: 6,
	mark: 0b11,
};
// const P: BitsField = BitsField {
// 	position: 5,
// 	mark: 0b1,
// };
// const X: BitsField = BitsField {
// 	position: 4,
// 	mark: 0b1,
// };

const CC: BitsField = BitsField {
	position: 0,
	mark: 0b1111,
};

const M: BitsField = BitsField {
	position: 7,
	mark: 0b1,
};

const PT: BitsField = BitsField {
	position: 0,
	mark: 0b1111111,
};

#[derive(Debug)]
pub(crate) struct RtpHead {
	pub(crate) first: u8,
	pub(crate) second: u8,
	pub(crate) seq_num: u16,
	pub(crate) timestamp: u32,

	pub(crate) ssrc: u32,
	pub(crate) csrc: Vec<u32>,
}

impl Codec for RtpHead {
	fn write_to(&self, buf: &mut BytesMut) {
		buf.put_u8(self.first);
		buf.put_u8(self.second);
		buf.put_u16(self.seq_num);
		buf.put_u32(self.timestamp);
		buf.put_u32(self.ssrc);
		for csrc in self.csrc.iter() {
			buf.put_u32(*csrc);
		}
	}

	fn from_bytes(buf: &mut Bytes) -> tools::ResultEx<Self>
	where
		Self: Sized,
	{
		if buf.len() < 12 {
			return Err(Error::IOError("rtp head len is less than 12".to_owned()));
		}

		let first = buf[0];
		let second = buf[1];
		let seq_num = unsafe { u16::from_ne_bytes(*(&buf[2..4] as *const _ as *const [_; 2])) };
		let timestamp = unsafe { u32::from_ne_bytes(*(&buf[4..8] as *const _ as *const [_; 4])) };
		let ssrc = unsafe { u32::from_ne_bytes(*(&buf[8..12] as *const _ as *const [_; 4])) };
		buf.advance(12);
		let cc = get_bits_value(first, &CC).into();
		let mut csrc = Vec::with_capacity(cc);
		for _ in 0..cc {
			csrc.push(buf.get_u32_ne());
		}

		Ok(Self {
			first,
			second,
			seq_num,
			timestamp,
			ssrc,
			csrc,
		})
	}
}

impl RtpHead {
	pub(crate) fn new(payload_type: u8, seq_num: u16, mark: bool, timestamp: u32, ssrc: u32) -> Self {
		let first = write_to_bits(0, &V, 2);
		let second = if mark { write_to_bits(0, &M, 1) } else { 0 };
		let second = write_to_bits(second, &PT, payload_type);

		Self {
			first,
			second,
			seq_num,
			timestamp,
			ssrc,
			csrc: Vec::default(),
		}
	}

	// pub(crate) fn version(&self) -> u8 {
	// 	get_bits_value(self.first, &V)
	// }

	// pub(crate) fn padding(&self) -> bool {
	// 	get_bits_bool(self.first, &P)
	// }
	// pub(crate) fn extension(&self) -> bool {
	// 	get_bits_bool(self.first, &X)
	// }
	// pub(crate) fn csrc_count(&self) -> u8 {
	// 	get_bits_value(self.first, &CC)
	// }
	// pub(crate) fn marker(&self) -> bool {
	// 	get_bits_bool(self.second, &M)
	// }
	// pub(crate) fn payload_type(&self) -> u8 {
	// 	get_bits_value(self.second, &PT)
	// }

	///读出相对应rtp包里面的payload type值.
	pub(crate) fn load_payload_type(buf: &[u8]) -> u8 {
		get_bits_value(buf[1], &PT)
	}
}
